<template>
  <el-skeleton
    ref="elSkeletonRef"
    class="el-skeleton"
    :rows="rows <= 0 ? 8 : rows - 1"
    :animated="animated"
    :loading="loading"
    style="width: 100%; height: 100%; overflow: hidden"
  ></el-skeleton>
</template>

<script setup lang="ts">
  import { useThrottleFn } from '@vueuse/core';
  import type { PropType } from 'vue';
  const props = defineProps({
    /** 组件的高度 */
    height: { type: Number as PropType<number | undefined>, default: undefined },
    /** 是否使用动画 */
    animated: { type: Boolean, default: true },
    /** 是否显示加载结束后的 DOM 结构	 */
    loading: { type: Boolean, default: true },
  });

  /** skeleton每一条的高度  */
  const skeletonRowHeight = 32;

  /** 一共渲染多少条 */
  const rows = ref(Math.trunc((props.height || 320) / skeletonRowHeight));
  watch(
    () => props.height,
    (val) => {
      if (typeof val === 'number') {
        rows.value = Math.trunc(val / skeletonRowHeight);
      }
    }
  );

  const elSkeletonRef: $RefComp<'ElSkeleton'> = ref(null);
  const myObserver = new ResizeObserver(
    useThrottleFn(() => {
      const divDom: HTMLElement | undefined = elSkeletonRef.value?.$el;
      if (divDom) {
        rows.value = Math.trunc((divDom.clientHeight + skeletonRowHeight / 2) / skeletonRowHeight);
      }
    }, 50)
  );

  onMounted(() => {
    const divDom: HTMLElement | undefined = elSkeletonRef.value?.$el || undefined;
    if (divDom) {
      setTimeout(() => {
        rows.value = Math.trunc((divDom.clientHeight + skeletonRowHeight / 2) / skeletonRowHeight);
      }, 10);
      elSkeletonRef.value && myObserver.observe(divDom);
    }
  });

  onUnmounted(() => {
    myObserver.disconnect();
  });
</script>

<style scoped lang="scss">
  .el-skeleton {
    @include flex(column, nowrap, center, flex-start, flex-start);

    > :deep(.el-skeleton__item) {
      display: block; // 解决默认 inline-block 会有间隙的问题
    }
  }
</style>
